package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.SignUtils;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.PSystemConfig;
import com.ruoyi.system.domain.PUserSign;
import com.ruoyi.system.domain.bo.PUserSignBo;
import com.ruoyi.system.domain.vo.PUserSignVo;
import com.ruoyi.system.mapper.PSystemConfigMapper;
import com.ruoyi.system.mapper.PUserSignMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.IPUserSignService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 用户签到Service业务层处理
 *
 * @author ruoyi
 * @date 2022-08-05
 */
@RequiredArgsConstructor
@Service
public class PUserSignServiceImpl implements IPUserSignService {

    private final PUserSignMapper baseMapper;
    private final PSystemConfigMapper configMapper;
    private final SysUserMapper userMapper;

    /**
     * 查询用户签到
     */
    @Override
    public PUserSignVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询用户签到列表
     */
    @Override
    public TableDataInfo<PUserSignVo> queryPageList(PUserSignBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PUserSign> lqw = buildQueryWrapper(bo);
        Page<PUserSignVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询用户签到列表
     */
    @Override
    public List<PUserSignVo> queryList(PUserSignBo bo) {
        LambdaQueryWrapper<PUserSign> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PUserSign> buildQueryWrapper(PUserSignBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PUserSign> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getUserId() != null, PUserSign::getUserId, bo.getUserId());
        lqw.eq(bo.getSignScore() != null, PUserSign::getSignScore, bo.getSignScore());
        lqw.eq(bo.getSeriesDays() != null, PUserSign::getSeriesDays, bo.getSeriesDays());
        lqw.eq(bo.getSignNums() != null, PUserSign::getSignNums, bo.getSignNums());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), PUserSign::getType, bo.getType());
        lqw.eq(bo.getSignTime() != null, PUserSign::getSignTime, bo.getSignTime());
        lqw.eq(StringUtils.isNotBlank(bo.getUserType()), PUserSign::getUserType, bo.getUserType());
        return lqw;
    }

    /**
     * 新增用户签到
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertByBo(PUserSignBo bo) {
        PUserSign add = BeanUtil.toBean(bo, PUserSign.class);
        Long userId = LoginHelper.getUserId();
        add.setUserId(userId);
        LambdaQueryWrapper<PUserSign> query = new QueryWrapper<PUserSign>().lambda()
            .eq(PUserSign::getUserId, userId)
            .eq(PUserSign::getType, SignUtils.SIGN_TYPE);
        List<PSystemConfig> signConfig = configMapper.selectList(new LambdaQueryWrapper<PSystemConfig>().eq(PSystemConfig::getType, SignUtils.SIGN_DICT));
        int signIntegral;
        if (CollectionUtil.isNotEmpty(signConfig)) {
            signIntegral = signConfig.get(0).getIntegral();
        } else {
            signIntegral = SignUtils.DEFAULT_SCORE;
        }
        // 判断是否已经初始化签到
        List<PUserSign> records = baseMapper.selectList(query);
        PUserSign sign;
        if (CollectionUtil.isNotEmpty(records)) {
            sign = records.get(0);
            Date signTime = sign.getSignTime();
            Date nowSignTime = new Date();
            boolean sameDay = isSameDay(signTime, nowSignTime);
            if (sameDay) {
                throw new ServiceException("请勿重复签到！");
            }

            // 填充天数
            Integer seriesDays = sign.getSeriesDays();
            sign.setSeriesDays(++seriesDays);
            sign.setSignScore(sign.getSignScore() + signIntegral);
            sign.setSignTime(new Date());

            baseMapper.updateById(sign);
        } else {
            sign = new PUserSign()
                .setSignScore(signIntegral)
                .setSignNums(SignUtils.DAY)
                .setSignTime(new Date())
                .setType(SignUtils.SIGN_TYPE)
                .setUserId(userId)
                .setSeriesDays(1);

            baseMapper.insert(sign);

        }

        // 同步到用户表中
        SysUser sysUser = userMapper.selectById(userId);
        sysUser.setIntegral(sign.getSignScore());
        userMapper.updateById(sysUser);

        return sign.getSignScore();
    }

    /**
     * 判断是否是同一天
     */
    public static boolean isSameDay(Date date1, Date date2) {
        if (date1 != null && date2 != null) {
            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(date1);
            Calendar cal2 = Calendar.getInstance();
            cal2.setTime(date2);
            return isSameDay(cal1, cal2);
        } else {
            throw new IllegalArgumentException("参数不能为空！");
        }
    }

    public static boolean isSameDay(Calendar cal1, Calendar cal2) {
        if (cal1 != null && cal2 != null) {
            // 判断某世纪中某年某天是否一样
            return cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
        } else {
            throw new IllegalArgumentException("参数不能为空！");
        }
    }

    /**
     * 修改用户签到
     */
    @Override
    public Boolean updateByBo(PUserSignBo bo) {
        PUserSign update = BeanUtil.toBean(bo, PUserSign.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PUserSign entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除用户签到
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
